package com.nanchen.compresshelper;


import ohos.global.resource.NotExistException;
import ohos.global.resource.ResourceManager;

import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;

import java.io.File;
import java.io.IOException;

/**
 * Bitmap 压缩相关操作工具类
 * <p>
 * <p>
 * <p>
 * 原理不明白请查看我博客：http://www.cnblogs.com/liushilin/p/6116759.html
 * <p>
 * Author: nanchen
 * Email: liushilin520@foxmail.com
 * Date: 2017-02-13  15:43
 */

public class ImageUtil {
    /**
     * 计算图片的压缩比率
     *
     * @param options   参数
     * @param reqWidth  目标的宽度
     * @param reqHeight 目标的高度
     * @param pathName  路径
     * @return 计算的SampleSize
     */
    private static int calculateInSampleSize(ImageSource.DecodingOptions options, String pathName, int reqWidth, int reqHeight) {
        // 源图片的高度和宽度
        Size size = options.desiredSize;
        int height = size.height;
        int width = size.width;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }


    /**
     * 计算图片的压缩比率
     *
     * @param options   参数
     * @param reqWidth  目标的宽度
     * @param reqHeight 目标的高度
     * @return 计算的SampleSize
     */
    private static int calculateInSampleSize(ImageSource.DecodingOptions options, int reqWidth, int reqHeight) {
        // 源图片的高度和宽度
        Size size = options.desiredSize;
        int height = size.height;
        int width = size.width;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

    /**
     * 从Resources中加载图片
     *
     * @param res       Resource
     * @param resId     资源id
     * @param reqWidth  请求宽度
     * @param reqHeight 请求高度
     * @return Bitmap
     */
    public static PixelMap decodeSampledBitmapFromResource(ResourceManager res, int resId, int reqWidth, int reqHeight) {

        final ImageSource.DecodingOptions options = new ImageSource.DecodingOptions();
        try {
            ImageSource imageSource = ImageSource.create(res.getResource(resId), null);
            options.desiredSize = imageSource.getImageInfo().size;
            imageSource.release();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        }


        options.sampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // 调用上面定义的方法计算inSampleSize值
        PixelMap src = null;
        try {
            ImageSource source = ImageSource.create(res.getResource(resId), null);
            src = source.createPixelmap(options); // 载入一个稍大的缩略图
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        }

        return createScaleBitmap(src, reqWidth, reqHeight, options.sampleSize); // 进一步得到目标大小的缩略图
    }

    /**
     * 通过传入的bitmap，进行压缩，得到符合标准的bitmap
     *
     * @param src       Bitmap源图
     * @param dstWidth  宽度
     * @param dstHeight 高度
     * @return 新的Bitmap
     */
    private static PixelMap createScaleBitmap(PixelMap src, int dstWidth, int dstHeight, int inSampleSize) {
        //如果inSampleSize是2的倍数，也就说这个src已经是我们想要的缩略图了，直接返回即可。
        if (inSampleSize % 2 == 0) {
            return src;
        }
        if (src == null) {
            return null;
        }

        // 如果是放大图片，filter决定是否平滑，如果是缩小图片，filter无影响，我们这里是缩小图片，所以直接设置为false
        Rect rect = new Rect(0, 0, dstWidth, dstHeight);
        PixelMap dst = PixelMap.create(src, rect, null); //根据记录的绘图命令的给定图片源创建一个位图

        if (src != dst) { // 如果没有缩放，那么不回收
            src.isReleased(); // 释放Bitmap的native像素数组
        }
        return dst;
    }

    /**
     * 从SD卡上加载图片
     *
     * @param pathName  路径
     * @param reqWidth  请求宽度
     * @param reqHeight 请求高度
     * @return Bitmap
     */
    public static PixelMap decodeSampledBitmapFromFile(String pathName, int reqWidth, int reqHeight) {
        final ImageSource.DecodingOptions options = new ImageSource.DecodingOptions();
        ImageSource imageSource = ImageSource.create(pathName, null);
        Size size = imageSource.getImageInfo().size;
        options.desiredSize = size;
        imageSource.release();
        options.sampleSize = calculateInSampleSize(options, pathName, reqWidth, reqHeight);
        ImageSource imageSource1 = ImageSource.create(pathName, null);
        PixelMap pixelMap = imageSource1.createPixelmap(options);
        return createScaleBitmap(pixelMap, reqWidth, reqHeight, options.sampleSize);
    }

    /**
     * 删除临时图片
     *
     * @param path 图片路径
     */
    public static void deleteTempFile(String path) {
        File file = new File(path);
        if (file.exists()) {
            file.delete();
        }
    }
}
